package com.life.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.life.constant.FileConstant;
import com.life.mapper.FileMapper;
import com.life.pojo.dto.FileQueryDTO;
import com.life.pojo.entity.File;
import com.life.pojo.vo.FileVO;
import com.life.properties.UploadProperties;
import com.life.service.FileService;
import com.life.utils.FileUploadUtils;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.time.LocalDateTime;


@Service
@Slf4j
public class FileServiceImpl implements FileService {

    @Autowired
    private FileMapper FileMapper;

    @Autowired
    private UploadProperties uploadProperties;

    /**
     * 保存文件
     *
     * @param file
     * @param type
     * @return
     */
    @Override
    public FileVO save(MultipartFile file, String type) throws IOException {
        //获取原始文件名
        String originalFilename = file.getOriginalFilename();
        //截取原始文件名的后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        //获取文件大小
        long size = file.getSize();
        //获取文件md5值
        String fileMD5 = FileUploadUtils.getFileMD5(file);
        //获取文件的前256KB的md5值
        String first256KBMD5 = FileUploadUtils.getFirst256KBMD5(file);
        //判断文件是否已经上传过
        File fileByCondition = getByCondition(size, fileMD5, first256KBMD5, type);
        if (fileByCondition != null) {
            FileVO fileVO = new FileVO();
            BeanUtils.copyProperties(fileByCondition, fileVO);
            fileVO.setIsRepeated(true);
            return fileVO;
        }
        //获取下一个文件ID
        String nextId = getNextId(FileConstant.File_DEFAULT_PREFIX);
        String fileType = FileConstant.FILE;
        switch (type) {
            //图片
            case FileConstant.IMG:
                return saveImage(originalFilename,file, suffix, size, fileMD5, first256KBMD5);
            //视频
            case FileConstant.MEDIA:
                //获取下一个视频ID
                nextId = getNextId(FileConstant.MEDIA_DEFAULT_PREFIX);
                fileType = FileConstant.MEDIA;
            default:
                //新文件名
                String newFileName = nextId + suffix;
                //新文件路径
                String path = uploadProperties.getUploadPath() + newFileName;
                //上传文件
                FileUploadUtils.upload(file, path);
                //创建文件对象
                File video = File.builder().
                        name(originalFilename).
                        type(fileType).
                        size(size).
                        fileMD5(fileMD5).
                        first256KBMD5(first256KBMD5).
                        createTime(LocalDateTime.now()).
                        path(uploadProperties.getAccessPath() + newFileName).
                        build();
                FileMapper.save(video);
                FileVO fileVO = new FileVO();
                BeanUtils.copyProperties(video, fileVO);
                return fileVO;
        }
    }

    private FileVO saveImage(String originalFilename, MultipartFile file, String suffix, long size, String fileMD5, String first256KBMD5) throws IOException {
        //获取下一个图片ID
        String nextId = getNextId(FileConstant.IMG_DEFAULT_PREFIX);
        //新文件名
        String newFileName = nextId + suffix;
        //读取图片
        BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
        //新文件路径
        String path = uploadProperties.getUploadPath() + newFileName;
        //上传文件
        FileUploadUtils.upload(file, path);
        //创建图片对象
        File picture = File.builder().
                name(originalFilename).
                type(FileConstant.IMG).
                width(bufferedImage.getWidth()).
                height(bufferedImage.getHeight()).
                size(size).
                fileMD5(fileMD5).
                first256KBMD5(first256KBMD5).
                createTime(LocalDateTime.now()).
                build();
        if (size > 1024 * 1024) {
            log.info("图片大于1M，进行压缩处理");
            String thumbnailPath = nextId + "-thumbnail" + suffix;
            Thumbnails.of(bufferedImage).outputQuality(0.8).scale(0.5).toFile(uploadProperties.getUploadPath() + thumbnailPath);
            picture.setPath(uploadProperties.getAccessPath() + thumbnailPath);
        } else {
            picture.setPath(uploadProperties.getAccessPath() + newFileName);
        }
        FileMapper.save(picture);
        FileVO fileVO = new FileVO();
        BeanUtils.copyProperties(picture, fileVO);
        return fileVO;
    }

    /**
     * 获取下一个id
     *
     * @return
     */
    public String getNextId(String type) {
        // 获取最后一个文件
        File file = FileMapper.findLast(type);
        // 如果没有文件，返回默认id
        if (file == null) {
            return type + 1000;
        }
        // 获取最后一张文件的id
        String path = file.getPath();  //api/static/IMG_1000.jpg
        String name = path.substring(path.lastIndexOf("/") + 1); //IMG_1000.jpg
        // 截取id
        String idStr = name.substring(type.length(), name.lastIndexOf(".")).replaceAll("-thumbnail", "");
        // 转换为int
        long id = Long.parseLong(idStr);
        // 返回下一个id
        return type + (id + 1);
    }

    /**
     * 根据条件获取图片
     *
     * @param size
     * @param fileMD5
     * @param first256KBMD5
     * @return
     */
    public File getByCondition(Long size, String fileMD5, String first256KBMD5, String type) {
        return FileMapper.getByCondition(size, fileMD5, first256KBMD5, type);
    }

    @Override
    public Page<FileVO> list(FileQueryDTO fileQueryDTO) {
        if (fileQueryDTO.getPageNum() == null || fileQueryDTO.getPageSize() == null) {
            fileQueryDTO.setPageNum(1);
            fileQueryDTO.setPageSize(10);
        }
        PageHelper.startPage(fileQueryDTO.getPageNum(), fileQueryDTO.getPageSize());
        Page<FileVO> page = FileMapper.list(fileQueryDTO);
        return page;
    }

    @Override
    public void delete(Long id) {
        FileMapper.delete(id);
    }

    @Override
    public void update(File file) {
        FileMapper.update(file);
    }

}
